import re
import django_redis
from django.contrib.auth import login
from django.shortcuts import render, redirect, reverse
from django.http import JsonResponse, HttpResponse, HttpResponseForbidden
from django.views.generic import View
from AgentLogin import AgentLogin
from django.conf import settings
from .models import QQAuthUser
from .utils import *


# create your views here
from userapp.models import Users


class QQLoginURLView(View):
    def get(self, request):
        """
        获取QQ扫码登录链接地址
        :param request:
        :return:
        """
        qq_url = AgentLogin.qq_url(settings.QQ_CLIENT_ID, settings.QQ_REDIRECT_URI)

        return JsonResponse({'code': '200', 'errormsg': 'OK', 'login_url': qq_url})


class QQAuthUserView(View):
    def get(self, request):
        """
        获取openid
        :param request:
        :return:
        """
        # 获取code参数
        code = request.GET.get('code', '')

        if not code:
            return HttpResponseForbidden('缺少code参数值!!')

        # 调用接口方法获取openid
        nikename, openid = AgentLogin.qq(settings.QQ_CLIENT_ID, settings.QQ_APP_KEY, settings.QQ_REDIRECT_URI, code)

        # 通过openid判断当前QQ用户是否绑定项目用户
        try:
            qq_uesr = QQAuthUser.objects.get(openid=openid)
        except QQAuthUser.DoesNotExist:
            # QQ未绑定用户
            # 1.加密openid数据
            sec_openid = generate_secret_openid(openid)
            # 2.传递加密数据到用户绑定页面
            return render(request, 'oauth/oauth_user.html', {'sec_openid': sec_openid})
        else:
            # QQ绑定了用户
            # 1.获取用户
            user = qq_uesr.user

            # 2.状态保持
            login(request, user)

            # 3.响应结果
            return redirect(reverse('newsapp:index'))

        return HttpResponse(openid)

    def post(self, request):
        """
        将当前访问QQ用户绑定项目用户
        :param request:
        :return:
        """
        # 1、接受参数
        sec_openid = request.POST.get('sec_openid', '')
        msgcode = request.POST.get('msgcode', '')
        phone = request.POST.get('phone', '')
        password = request.POST.get('password', '')
        # 2、校验参数
        # 判断参数是否齐全
        if not all([sec_openid, msgcode, phone, password]):
            return HttpResponseForbidden('缺少必传参数！！')

        # 判断手机号格式是否正确
        if not re.match(r'^1[3-9]\d{9}$', phone):
            return HttpResponseForbidden('手机号格式不正确！！')

        # 判断密码格式是否正确
        if not re.match(r'^\w{6,18}$', password):
            return HttpResponseForbidden('密码格式不正确！！')

        # 有效性校验
        redis_conn = django_redis.get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms%s' % phone)

        if sms_code_server is None:
            return render(request, 'oauth/oauth_user.html', {'sms_code_errmsg': '无效的短信验证码'})

        if msgcode != sms_code_server.decode():
            return render(request, 'oauth/oauth_user.html', {'sms_code_errmsg': '输入的短信验证码有误'})

        # 3、绑定用户
        # 判断openid是否有效
        openid = check_secret_openid(sec_openid)
        if not openid:
            return render(request, 'oauth/oauth_user.html', {'openid_errmsg': '⽆效的openid'})

        # 获取项目用户
        try:
            user = Users.objects.get(phone=phone)
        except Users.DoesNotExist:
            # 不存在则创建新用户
            user = Users.objects.create_user(username=phone, password=password, phone=phone)
        else:
            # 若用户已存在则判断当前项目用户密码是否正确
            if not user.check_password(password):
                return render(request, 'oauth/oauth_user.html', {'qq_login_errmsg': '用户名或密码错误'})

        # 绑定用户
        QQAuthUser.objects.create(user=user, openid=openid)

        # 状态保持
        login(request, user)
        # 4、响应结果
        return redirect(reverse('newsapp:index'))
